package 进程代理类

import "C"
import (
	"gitee.com/go_888/sunnynet/Call"
	public "gitee.com/go_888/sunnynet/public"
	"strconv"
)

func X取代理请求信息(消息ID int) (*ProxyRequest, bool) {
	messageIdLock.Lock()
	defer messageIdLock.Unlock()
	k := httpStorage[消息ID]
	if k == nil {
		return nil, false
	}
	return k, true
}
func X取WebSocket消息(消息ID int) (*public.WebsocketMsg, bool) {
	messageIdLock.Lock()
	defer messageIdLock.Unlock()
	k := wsStorage[消息ID]
	if k == nil {
		return nil, false
	}
	return k, true
}

// TCP请求回调 TCP请求处理回调
func (s *ProxyRequest) TCP请求回调(回调类型 int, 消息 *public.TcpMsg) {
	if s.X全局中间件信息.disableTCP {
		//由于用户可能在软件中途禁用TCP,所有这里允许触发关闭的回调
		if 回调类型 != public.X常量_TCP消息类型_连接关闭或失败 {
			//这里如果禁用了TCP,那么这里就不允许触发回调了，并且手动关闭连接
			TcpSceneLock.Lock()
			w := TcpStorage[s.X中间件回调唯一ID]
			TcpSceneLock.Unlock()
			if w == nil {
				return
			}
			w.L.Lock()
			_ = w.ConnSend.Close()
			_ = w.ConnServer.Close()
			w.L.Unlock()
			return
		}
	}
	LocalAddr := s.X原始TCP连接.RemoteAddr().String()
	hostname := s.X请求连接信息.String()
	pid, _ := strconv.Atoi(s.Pid)
	MessageId := X创建消息ID()
	if s.TcpCall < 10 {
		if s.GOTCP请求回调 != nil {
			Ams := &TcpConn{c: 消息, X消息ID: MessageId, X请求类型: 回调类型, X唯一ID: s.X中间件回调唯一ID, X本地地址: LocalAddr, X远程地址: hostname, X进程ID: pid, X中间件上下文: s.X全局中间件信息.SunnyContext}
			s.GOTCP请求回调(Ams)
		}
		return
	}
	messageIdLock.Lock()
	httpStorage[MessageId] = s
	messageIdLock.Unlock()

	if 回调类型 != public.X常量_TCP消息类型_客户端发送数据 && 回调类型 != public.X常量_TCP消息类型_客户端收到数据 && 回调类型 != public.X常量_TCP消息类型_即将开始连接 {
		Call.Call(s.TcpCall, s.X全局中间件信息.SunnyContext, LocalAddr, hostname, 回调类型, MessageId, []byte{}, 0, s.X中间件回调唯一ID, pid)
		messageIdLock.Lock()
		httpStorage[MessageId] = nil
		delete(httpStorage, MessageId)
		messageIdLock.Unlock()
		return
	}
	if 回调类型 == public.X常量_TCP消息类型_客户端发送数据 || 回调类型 == public.X常量_TCP消息类型_即将开始连接 {
		s.TCP收发数据.Send = 消息
	} else {
		s.TCP收发数据.Receive = 消息
	}
	Call.Call(s.TcpCall, s.X全局中间件信息.SunnyContext, LocalAddr, hostname, 回调类型, MessageId, 消息.Data.Bytes(), 消息.Data.Len(), s.X中间件回调唯一ID, pid)

	messageIdLock.Lock()
	httpStorage[MessageId] = nil
	delete(httpStorage, MessageId)
	messageIdLock.Unlock()
}

// HTTP发起请求回调 HTTP发起请求处理回调
func (s *ProxyRequest) HTTP发起请求回调() {

	if s.HTTP响应体 != nil {
		if s.HTTP响应体.Body != nil {
			_ = s.HTTP响应体.Body.Close()
		}
	}
	s.HTTP响应体 = nil
	MessageId := X创建消息ID()
	pid, _ := strconv.Atoi(s.Pid)
	if s.HTTP请求回调 < 10 {
		if s.GOHTTP请求回调 != nil {
			m := &HttpConn{X唯一ID: s.X中间件回调唯一ID, X消息ID: MessageId, PID: pid, SunnyContext: s.X全局中间件信息.SunnyContext, X请求类型: public.X常量_HTTP消息类型_发送请求, X请求体: s.HTTP请求体, X响应体: nil, X错误信息: "", X代理信息: s.X设置指定代理, X来源IP地址: s.X原始TCP连接.RemoteAddr().String()}
			s.GOHTTP请求回调(m)
			s.HTTP响应体 = m.X响应体
		}
		return
	}
	Method := s.HTTP请求体.Method
	Url := s.HTTP请求体.URL.String()
	messageIdLock.Lock()
	httpStorage[MessageId] = s
	messageIdLock.Unlock()

	Call.Call(s.HTTP请求回调, s.X全局中间件信息.SunnyContext, s.X中间件回调唯一ID, MessageId, public.X常量_HTTP消息类型_发送请求, Method, Url, "", pid)

	messageIdLock.Lock()
	httpStorage[MessageId] = nil
	delete(httpStorage, MessageId)
	messageIdLock.Unlock()

}

// HTTP请求完成回调 HTTP请求完成处理回调
func (s *ProxyRequest) HTTP请求完成回调() {
	pid, _ := strconv.Atoi(s.Pid)
	if s.HTTP请求回调 < 10 {
		if s.GOHTTP请求回调 != nil {
			m := &HttpConn{X唯一ID: s.X中间件回调唯一ID, X消息ID: X创建消息ID(), PID: pid, SunnyContext: s.X全局中间件信息.SunnyContext, X请求类型: public.X常量_HTTP消息类型_接收完成, X请求体: s.HTTP请求体, X响应体: s.HTTP响应体, X错误信息: "", X来源IP地址: s.X原始TCP连接.RemoteAddr().String()}
			s.GOHTTP请求回调(m)
		}
		return
	}
	MessageId := X创建消息ID()
	Method := s.HTTP请求体.Method
	Url := s.HTTP请求体.URL.String()

	messageIdLock.Lock()
	httpStorage[MessageId] = s
	messageIdLock.Unlock()

	Call.Call(s.HTTP请求回调, s.X全局中间件信息.SunnyContext, s.X中间件回调唯一ID, MessageId, public.X常量_HTTP消息类型_接收完成, Method, Url, "", pid)

	messageIdLock.Lock()
	httpStorage[MessageId] = nil
	delete(httpStorage, MessageId)
	messageIdLock.Unlock()
}

// Websocket请求回调 HTTP->Websocket请求处理回调
func (s *ProxyRequest) Websocket请求回调(State int, Method, Url string, msg *public.WebsocketMsg, 消息ID int) {
	pid, _ := strconv.Atoi(s.Pid)
	//Websocket消息
	if s.wsCall < 10 {
		if s.wsGoCall != nil {
			m := &WsConn{Pid: pid, X请求类型: State, SunnyContext: s.X全局中间件信息.SunnyContext, X请求地址: Url, c: msg, X消息ID: 消息ID, X唯一ID: s.X中间件回调唯一ID, X请求体: s.HTTP请求体, X来源IP地址: s.X原始TCP连接.RemoteAddr().String()}
			s.wsGoCall(m)
		}
		return
	}
	Call.Call(s.wsCall, s.X全局中间件信息.SunnyContext, s.X中间件回调唯一ID, 消息ID, State, Method, Url, pid, msg.Mt)
}

// HTTP请求失败回调 HTTP请求失败处理回调
func (s *ProxyRequest) HTTP请求失败回调(错误 error) {
	pid, _ := strconv.Atoi(s.Pid)
	if s.HTTP请求回调 < 10 {
		if s.GOHTTP请求回调 != nil {
			m := &HttpConn{X唯一ID: s.X中间件回调唯一ID, X消息ID: X创建消息ID(), PID: pid, SunnyContext: s.X全局中间件信息.SunnyContext, X请求类型: public.X常量_HTTP消息类型_请求失败, X请求体: s.HTTP请求体, X响应体: nil, X错误信息: 错误.Error(), X来源IP地址: s.X原始TCP连接.RemoteAddr().String()}
			s.GOHTTP请求回调(m)
		}
		return
	}
	//请求失败
	MessageId := X创建消息ID()
	Method := s.HTTP请求体.Method

	Url := "Unknown URL"
	if s.HTTP请求体.URL != nil {
		Url = s.HTTP请求体.URL.String()
	}

	messageIdLock.Lock()
	httpStorage[MessageId] = s
	messageIdLock.Unlock()

	Call.Call(s.HTTP请求回调, s.X全局中间件信息.SunnyContext, s.X中间件回调唯一ID, MessageId, public.X常量_HTTP消息类型_请求失败, Method, Url, 错误.Error(), pid)

	messageIdLock.Lock()
	httpStorage[MessageId] = nil
	delete(httpStorage, MessageId)
	messageIdLock.Unlock()

}
